package com.study.hisapi.controller;

import cn.hutool.json.JSONUtil;
import com.study.hisapi.constant.HisServiceConstant;
import com.study.hisapi.constant.HospitalServiceConstant;
import com.study.hisapi.domain.bo.core.R;
import com.study.hisapi.domain.bo.core.RequestBo;
import com.study.hisapi.service.AbstractHisService;
import com.study.hisapi.utils.Context;
import com.study.hisapi.utils.ContextUtils;
import com.study.hisapi.utils.ValidatedUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * His Api
 *
 * @author LiXiao
 * @date 2024/4/11
 */
@Slf4j
@RestController
@RequestMapping("/request")
public class RequestController {
    @Resource
    private Map<String, AbstractHisService> abstractHisServiceMap;


    /**
     * His 公用请求入口
     */
    @PostMapping
    public R<Object> request(@RequestBody RequestBo requestBo) {
        log.info("RequestData：{}", JSONUtil.toJsonStr(requestBo));
        Context currentContext = ContextUtils.getCurrentContext();

        // 判断 service 是否在常量中
        String service = requestBo.getService();
        currentContext.setService(service);
        boolean containsService = HisServiceConstant.constantsSet.contains(service);
        if (!containsService) {
            return R.fail("服务名称错误，请联系系统管理员获取");
        }

        // 判断 hospital 是否在常量中
        String hospital = requestBo.getHospital();
        currentContext.setHospital(hospital);
        boolean containsHospital = HospitalServiceConstant.constantsSet.contains(hospital);
        if (!containsHospital) {
            return R.fail("医院名称错误，请联系系统管理员获取");
        }

        currentContext.setHisUrl(requestBo.getHisUrl());
        Set<ConstraintViolation<RequestBo>> violations = ValidatedUtils.isValid(requestBo);
        if (!violations.isEmpty()) {
            List<String> errMsg = new ArrayList<>();
            for (ConstraintViolation<RequestBo> violation : violations) {
                errMsg.add(violation.getPropertyPath() + ":" + violation.getMessage());
            }
            return R.fail(String.join("; ", errMsg));
        }

        AbstractHisService abstractHisService = abstractHisServiceMap.get(service);
        return R.ok(abstractHisService.request(requestBo));
    }
}
